﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Tank
{
    class TankBot : Tank
    {
        Random rnd = new Random();
        public string str;
        private bool[,] visited = new bool[10, 10];
        public int[] BFS = new int[100];
        private int[] pred = new int[100];
        //public int[] path = new int[100];
        private int direction = 1; //0-hore, 1-dole, 2-dolava, 3-doprava
        private int gotoX, gotoY;
        private int lastx, lasty;
        private int surX, surY;

        public TankBot()
        {
            this.x = 5 * Map.sirka + 10;
            this.y = 0 * Map.vyska + 10;
            this.gotoX = this.x;
            this.gotoY = this.y;
        }
        public TankBot(int x, int y)
        {
            this.pozX = x;
            this.pozY = y;
            this.x = x * Map.sirka;
            this.y = y * Map.vyska;
            this.gotoX = this.x;
            this.gotoY = this.y;

        }

        public void Krok()
        {
            if (vyrovnany())
            {
                this.BFSOpp();
                str = this.surX.ToString() + " " + this.surY.ToString();
                if (opponent() == true)
                {
                    this.nasmeruj();
                    //this.direction = 5;
                    //if (rnd.Next(10) == 10) 
                    this.shot();
                    this.gotoXY(this.lastx, this.lasty);
                }
                else
                {
                    this.lastx = this.pozX;
                    this.lasty = this.pozY;
                    this.gotoXY(this.surX, this.surY);
                    this.smer = this.direction;
                }
            }
            else
            {
                this.Move(this.direction);
                if (opponent() == false && this.direction == 5)
                {
                    BFSOpp();
                    this.gotoXY(this.surX, this.surY);
                    this.smer = this.direction;
                }
            }

            //if (opponent() == true)
            //    if (rnd.Next(10) == 1)
            //        this.shot();

        }

        private void nasmeruj()
        {
            if (this.pozX == Share.tankX)
            {
                if (this.pozY < Share.tankY) this.direction = this.smer = 1; //this.Move(1);
                else
                    this.direction = this.smer = 0; //this.Move(0);
            }
            if (this.pozY == Share.tankY)
            {
                if (this.pozX < Share.tankX) this.direction = this.smer = 3; //this.Move(3);
                else
                    this.direction = this.smer = 2; //this.Move(2);
            }
        }

        private bool vyrovnany()
        {
            switch (this.direction)
            {
                case 0: if (this.y <= this.gotoY + (Map.vyska - Tank.sizeY))
                    {
                        return true;
                    }
                    break;
                case 1: if (this.y >= this.gotoY)
                    {
                        return true;
                    }
                    break;
                case 2: if (this.x <= this.gotoX + (Map.sirka - Tank.sizeX))
                    {
                        return true;
                    }
                    break;
                case 3: if (this.x >= this.gotoX)
                    {
                        return true;
                    }
                    break;

                case 5: return false;
            }
            return false;
        }

        public bool opponent()
        {
            bool b = Share.opp[pozY, pozX];
            return b;
        }

        private void BFSOpp()
        {
            for (int i = 0; i < 10; i++)
                for (int j = 0; j < 10; j++)
                {
                    this.visited[i, j] = false;
                }

            int p1 = 0;
            int p2 = 0;
            int Y = pozY;
            int X = pozX;

            this.BFS[0] = 10 * X + Y;

            this.pred[0] = -1;

            this.visited[X, Y] = true;

            bool end = false;

            while (end == false) //&& Share.opp[this.BFS[p2] / 10, this.BFS[p2] % 10] == false)
            {
                // this.BFS
                X = this.BFS[p1] / 10;
                Y = this.BFS[p1] % 10;

                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        if ((i != j && i != -j) && end == false)
                        {
                            if (X + i < 10 && X + i >= 0 && Y + j < 10 && Y + j >= 0)
                            {
                                if (visited[X + i, Y + j] == false && Map.map[Y + j, X + i] != 'P')
                                {
                                    //if (X + i > 0 && X + i < 10 && Y + j > 0 && Y + j < 10 && Share.opp[Y + j, X + i] == true)
                                    if (X + i == Share.player.x / Map.sirka && Y + j == Share.player.y / Map.vyska)
                                    {
                                        end = true;
                                        this.visited[X + i, Y + j] = true;
                                        p2++;
                                        this.BFS[p2] = 10 * (X + i) + (Y + j);
                                        this.pred[p2] = this.BFS[p1];
                                    }
                                    else
                                    {
                                        this.visited[X + i, Y + j] = true;
                                        p2++;
                                        this.BFS[p2] = 10 * (X + i) + (Y + j);
                                        this.pred[p2] = this.BFS[p1];
                                    }
                                }

                            }
                        }
                    }
                }
                p1++;
                if (p1 == p2) end = true;
            }


            int i2 = 0;

            //int[] path2 = new int[100];

            //path2[i2] = this.BFS[p2];

            this.surX = this.BFS[p2] / 10;
            this.surY = this.BFS[p2] % 10;

            int prev = this.pred[p2];

            while (p2 > 0)
            {
                if (this.BFS[p2] == prev)
                {
                    i2++;
                    this.surX = this.BFS[p2] / 10;
                    this.surY = this.BFS[p2] % 10;
                    prev = this.pred[p2];
                }
                //else                          //je to mozne, ze chyba seknutia bota moze sposobit tato vetva
                //{
                //    p2--;
                //}
                p2--;
            }

            //for (int i = 0; i <= i2; i++)
            //{
            //    path[i2 - i] = path2[i];
            //}
        }

        private void gotoXY(int sx, int sy)
        {
            this.gotoX = sx * Map.sirka;
            this.gotoY = sy * Map.vyska;

            if (this.pozX == sx)
            {
                if (this.pozY < sy)
                {
                    this.direction = 1;
                }
                else
                {
                    if (this.pozY > sy)
                        this.direction = 0;
                }
            }
            else
                if (pozY == sy)
                {
                    if (pozX > sx)
                    {
                        this.direction = 2;
                    }
                    else
                    {
                        if (pozX < sx)
                            this.direction = 3;
                    }
                }
            //this.Move(this.direction);
        }
    }
}